import prisma from '../lib/prisma';
import { generateUniqueSlug } from '../utils/slug';
import sanitizeHtml from 'sanitize-html';

const sanitizeOptions: sanitizeHtml.IOptions = {
  allowedTags: false, // 允许所有标签
  allowedAttributes: false, // 允许所有属性
  allowedIframeHostnames: ['www.bilibili.com','bilibili.com', 'player.bilibili.com'] // 允许所有iframe主机，并允许 player.bilibili.com
};

export interface CreateArticleData {
  title: string;
  content: string;
  summary?: string;
  author: string;
  userId?: number;
  categoryId: number;
  status: boolean;
  coverImage?: string;
  tags?: string[];
  isTop?: boolean;
  isRecommend?: boolean;
}

export interface UpdateArticleData {
  title?: string;
  content?: string;
  summary?: string;
  author?: string;
  userId?: number;
  categoryId?: number;
  status?: boolean;
  coverImage?: string;
  tags?: string[];
  isTop?: boolean;
  isRecommend?: boolean;
}

export interface ArticleQueryParams {
  page?: number;
  limit?: number;
  categoryId?: number;
  status?: boolean;
  keyword?: string;
  userId?: number;
  isTop?: boolean;
  isRecommend?: boolean;
  sort?: string;
}

export class ArticleService {
  // 创建文章
  async createArticle(data: CreateArticleData, userId: number) {
    try {
      // 生成唯一的slug
      const existingSlugs = await this.getExistingSlugs();
      const slug = generateUniqueSlug(existingSlugs);

      // 净化HTML内容
      const cleanContent = sanitizeHtml(data.content, sanitizeOptions);

      const article = await prisma.article.create({
      data: {
        ...data,
        content: cleanContent,
        slug,
        tags: data.tags || [],
        publishedAt: data.status ? new Date() : null,
        userId: userId, // 设置用户ID
      } as any,
        include: {
          category: true,
          user: true,
        },
      });

      return { success: true, data: article };
    } catch (error) {
      console.error('创建文章失败:', error);
      return { success: false, error: '创建文章失败' };
    }
  }

  // 根据ID获取文章
  async getArticleById(id: number) {
    try {
      const article = await prisma.article.findFirst({
        where: {
          id,
          display: true, // 只显示未软删除的数据
        },
        include: {
          category: true,
          user: true,
        },
      });

      if (!article) {
        return { success: false, error: '文章不存在' };
      }

      // 增加浏览量
      await prisma.article.update({
        where: { id },
        data: { views: { increment: 1 } },
      });

      return { success: true, data: article };
    } catch (error) {
      console.error('获取文章失败:', error);
      return { success: false, error: '获取文章失败' };
    }
  }

  // 根据slug获取文章
  async getArticleBySlug(slug: string) {
    try {
      console.log('查找slug:', slug);
      
      const article = await prisma.article.findFirst({
        where: {
          slug,
          display: true, // 只显示未软删除的数据
        },
        include: {
          category: true,
          user: true,
        },
      });

      console.log('查询结果:', article);

      if (!article) {
        return { success: false, error: '文章不存在' };
      }

      // 增加浏览量
      await prisma.article.update({
        where: { slug },
        data: { views: { increment: 1 } },
      });

      return { success: true, data: article };
    } catch (error) {
      console.error('获取文章失败:', error);
      return { success: false, error: '获取文章失败' };
    }
  }

  // 获取文章列表
  async getArticles(params: ArticleQueryParams = {}) {
    try {
      const {
        page = 1,
        limit = 10,
        categoryId,
        status,
        keyword,
        userId,
        isTop,
        isRecommend,
        sort,
      } = params;

      const skip = (page - 1) * limit;

      // 构建排序条件
      const orderBy: any[] = [];
      if (sort) {
        if (sort === 'hot') {
          orderBy.push({ views: 'desc' });
        } else if (sort === 'latest') {
          orderBy.push({ createdAt: 'desc' });
        } else {
          // 兼容旧的格式，例如：'views:desc'
          const [field, order] = sort.split(':');
          if (['createdAt', 'publishedAt', 'views', 'likes', 'comments'].includes(field) && ['asc', 'desc'].includes(order)) {
            orderBy.push({ [field]: order });
          }
        }
      }
      // 默认排序：置顶+推荐 > 置顶 > 推荐 > 普通，然后按发布时间排序
      // 注意：Prisma的复合排序可能不会按预期工作，我们需要在应用层进行排序
      orderBy.push({ publishedAt: 'desc' });
      orderBy.push({ createdAt: 'desc' });

      // 构建查询条件
      const where: any = {
        display: true, // 只显示未软删除的数据
      };
      if (categoryId) where.categoryId = categoryId;
      if (status !== undefined) where.status = status;
      if (isTop !== undefined) where.isTop = isTop;
      if (isRecommend !== undefined) where.isRecommend = isRecommend;
      if (userId) where.userId = userId;
      if (keyword) {
        where.OR = [
          { title: { contains: keyword, mode: 'insensitive' } },
          { content: { contains: keyword, mode: 'insensitive' } },
          { summary: { contains: keyword, mode: 'insensitive' } },
        ];
      }

      const [articles, total] = await Promise.all([
        prisma.article.findMany({
          where,
          include: {
            category: true,
            user: true,
          },
          orderBy,
          skip,
          take: limit,
        }),
        prisma.article.count({ where }),
      ]);

      // 自定义排序：置顶+推荐 > 置顶 > 推荐 > 普通
      const sortedArticles = articles.sort((a, b) => {
        // 计算优先级分数：置顶+推荐=4，置顶=3，推荐=2，普通=1
        const getPriority = (article: any) => {
          let priority = 1; // 普通文章
          if (article.isTop && article.isRecommend) priority = 4; // 置顶+推荐
          else if (article.isTop) priority = 3; // 置顶
          else if (article.isRecommend) priority = 2; // 推荐
          return priority;
        };

        const priorityA = getPriority(a);
        const priorityB = getPriority(b);

        // 先按优先级排序
        if (priorityA !== priorityB) {
          return priorityB - priorityA; // 优先级高的在前
        }

        // 优先级相同时，按发布时间排序
        const timeA = new Date(a.publishedAt || a.createdAt).getTime();
        const timeB = new Date(b.publishedAt || b.createdAt).getTime();
        return timeB - timeA; // 时间新的在前
      });

      const totalPages = Math.ceil(total / limit);

      return {
        success: true,
        data: {
          articles: sortedArticles,
          total,
          page,
          limit,
          totalPages,
        },
      };
    } catch (error) {
      console.error('获取文章列表失败:', error);
      return { success: false, error: '获取文章列表失败' };
    }
  }

  // 更新文章
  async updateArticle(id: number, data: UpdateArticleData) {
    try {
      const updateData: any = { ...data };

      // 如果有新内容，则净化
      if (data.content) {
        updateData.content = sanitizeHtml(data.content, sanitizeOptions);
      }

      // 如果状态从草稿变为发布，设置发布时间
      if (data.status === true) {
        const existingArticle = await prisma.article.findUnique({
          where: { id },
          select: { publishedAt: true },
        });

        if (!existingArticle?.publishedAt) {
          updateData.publishedAt = new Date();
        }
      }

      const article = await prisma.article.update({
        where: { id },
        data: updateData,
        include: {
          category: true,
          user: true,
        },
      });

      return { success: true, data: article };
    } catch (error) {
      console.error('更新文章失败:', error);
      return { success: false, error: '更新文章失败' };
    }
  }

  // 软删除文章
  async deleteArticle(id: number, deleteBy?: number) {
    try {
      await prisma.article.update({
        where: { id },
        data: {
          display: false,
          deleteBy: deleteBy || null,
          deleteAt: new Date(),
        },
      });

      return { success: true };
    } catch (error) {
      console.error('删除文章失败:', error);
      return { success: false, error: '删除文章失败' };
    }
  }

  // 获取文章统计
  async getArticleStats() {
    try {
      const [total, published, draft, top, recommend] = await Promise.all([
        prisma.article.count({ where: { display: true } }),
        prisma.article.count({ where: { status: true, display: true } }),
        prisma.article.count({ where: { status: false, display: true } }),
        prisma.article.count({ where: { isTop: true, display: true } }),
        prisma.article.count({ where: { isRecommend: true, display: true } }),
      ]);

      return {
        success: true,
        data: {
          total,
          published,
          draft,
          top,
          recommend,
        },
      };
    } catch (error) {
      console.error('获取文章统计失败:', error);
      return { success: false, error: '获取文章统计失败' };
    }
  }

  // 获取推荐文章
  async getRecommendArticles(limit: number = 5) {
    try {
      const articles = await prisma.article.findMany({
        where: {
          status: true,
          isRecommend: true,
          display: true, // 只显示未软删除的数据
        },
        include: {
          category: true,
          user: true,
        },
        orderBy: [
          { isTop: 'desc' },
          { publishedAt: 'desc' },
          { views: 'desc' },
        ],
        take: limit,
      });

      return { success: true, data: articles };
    } catch (error) {
      console.error('获取推荐文章失败:', error);
      return { success: false, error: '获取推荐文章失败' };
    }
  }

  // 获取置顶文章
  async getTopArticles(limit: number = 3) {
    try {
      const articles = await prisma.article.findMany({
        where: {
          status: true,
          isTop: true,
          display: true, // 只显示未软删除的数据
        },
        include: {
          category: true,
          user: true,
        },
        orderBy: [
          { publishedAt: 'desc' },
          { views: 'desc' },
        ],
        take: limit,
      });

      return { success: true, data: articles };
    } catch (error) {
      console.error('获取置顶文章失败:', error);
      return { success: false, error: '获取置顶文章失败' };
    }
  }

  // 获取已存在的slug列表
  private async getExistingSlugs(): Promise<string[]> {
    try {
      const articles = await prisma.article.findMany({
        select: { slug: true },
      });
      return articles.map((article: { slug: string }) => article.slug);
    } catch (error) {
      console.error('获取已存在slug失败:', error);
      return [];
    }
  }
} 